home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / mmdf / mmdf-IIb.43 / uip / ucbmail / tty.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-06-03  |  4.3 KB  |  235 lines

  1. /*
  2.  * Copyright (c) 1980 Regents of the University of California.
  3.  * All rights reserved.  The Berkeley software License Agreement
  4.  * specifies the terms and conditions for redistribution.
  5.  */
  6.  
  7. #ifndef lint
  8. static char *sccsid = "@(#)tty.c    5.2 (Berkeley) 6/21/85";
  9. #endif not lint
  10.  
  11. /*
  12.  * Mail -- a mail program
  13.  *
  14.  * Generally useful tty stuff.
  15.  */
  16.  
  17. #include "./rcv.h"
  18.  
  19. static    int    c_erase;        /* Current erase char */
  20. static    int    c_kill;            /* Current kill char */
  21. static    int    hadcont;        /* Saw continue signal */
  22. static    jmp_buf    rewrite;        /* Place to go when continued */
  23. #ifndef TIOCSTI
  24. static    int    ttyset;            /* We must now do erase/kill */
  25. #endif
  26.  
  27. /*
  28.  * Read all relevant header fields.
  29.  */
  30.  
  31. grabh(hp, gflags)
  32.     struct header *hp;
  33. {
  34.     struct sgttyb ttybuf;
  35.     int ttycont(), signull();
  36. #ifndef TIOCSTI
  37.     int (*savesigs[2])();
  38. #endif
  39.     int (*savecont)();
  40. #ifndef TIOCSTI
  41.     register int s;
  42. #endif  TIOCSTI
  43.  
  44. # ifdef VMUNIX
  45.     savecont = sigset(SIGCONT, signull);
  46. # endif VMUNIX
  47. #ifndef TIOCSTI
  48.     ttyset = 0;
  49. #endif
  50.     if (gtty(fileno(stdin), &ttybuf) < 0) {
  51.         perror("gtty");
  52.         return;
  53.     }
  54.     c_erase = ttybuf.sg_erase;
  55.     c_kill = ttybuf.sg_kill;
  56. #ifndef TIOCSTI
  57.     ttybuf.sg_erase = 0;
  58.     ttybuf.sg_kill = 0;
  59.     for (s = SIGINT; s <= SIGQUIT; s++)
  60.         if ((savesigs[s-SIGINT] = sigset(s, SIG_IGN)) == SIG_DFL)
  61.             sigset(s, SIG_DFL);
  62. #endif
  63.     if (gflags & GTO) {
  64. #ifndef TIOCSTI
  65.         if (!ttyset && hp->h_to != NOSTR)
  66.             ttyset++, stty(fileno(stdin), &ttybuf);
  67. #endif
  68.         hp->h_to = readtty("To: ", hp->h_to);
  69.         if (hp->h_to != NOSTR)
  70.             hp->h_seq++;
  71.     }
  72.     if (gflags & GSUBJECT) {
  73. #ifndef TIOCSTI
  74.         if (!ttyset && hp->h_subject != NOSTR)
  75.             ttyset++, stty(fileno(stdin), &ttybuf);
  76. #endif
  77.         hp->h_subject = readtty("Subject: ", hp->h_subject);
  78.         if (hp->h_subject != NOSTR)
  79.             hp->h_seq++;
  80.     }
  81.     if (gflags & GCC) {
  82. #ifndef TIOCSTI
  83.         if (!ttyset && hp->h_cc != NOSTR)
  84.             ttyset++, stty(fileno(stdin), &ttybuf);
  85. #endif
  86.         hp->h_cc = readtty("Cc: ", hp->h_cc);
  87.         if (hp->h_cc != NOSTR)
  88.             hp->h_seq++;
  89.     }
  90.     if (gflags & GBCC) {
  91. #ifndef TIOCSTI
  92.         if (!ttyset && hp->h_bcc != NOSTR)
  93.             ttyset++, stty(fileno(stdin), &ttybuf);
  94. #endif
  95.         hp->h_bcc = readtty("Bcc: ", hp->h_bcc);
  96.         if (hp->h_bcc != NOSTR)
  97.             hp->h_seq++;
  98.     }
  99. # ifdef VMUNIX
  100.     sigset(SIGCONT, savecont);
  101. # endif VMUNIX
  102. #ifndef TIOCSTI
  103.     ttybuf.sg_erase = c_erase;
  104.     ttybuf.sg_kill = c_kill;
  105.     if (ttyset)
  106.         stty(fileno(stdin), &ttybuf);
  107.     for (s = SIGINT; s <= SIGQUIT; s++)
  108.         sigset(s, savesigs[s-SIGINT]);
  109. #endif
  110. }
  111.  
  112. /*
  113.  * Read up a header from standard input.
  114.  * The source string has the preliminary contents to
  115.  * be read.
  116.  *
  117.  */
  118.  
  119. char *
  120. readtty(pr, src)
  121.     char pr[], src[];
  122. {
  123.     char ch, canonb[BUFSIZ];
  124.     int c, signull();
  125.     register char *cp, *cp2;
  126.  
  127.     fputs(pr, stdout);
  128.     fflush(stdout);
  129.     if (src != NOSTR && strlen(src) > BUFSIZ - 2) {
  130.         printf("too long to edit\n");
  131.         return(src);
  132.     }
  133. #ifndef TIOCSTI
  134.     if (src != NOSTR)
  135.         cp = copy(src, canonb);
  136.     else
  137.         cp = copy("", canonb);
  138.     fputs(canonb, stdout);
  139.     fflush(stdout);
  140. #else
  141.     cp = src == NOSTR ? "" : src;
  142.     while (c = *cp++) {
  143.         if (c == c_erase || c == c_kill) {
  144.             ch = '\\';
  145.             ioctl(0, TIOCSTI, &ch);
  146.         }
  147.         ch = c;
  148.         ioctl(0, TIOCSTI, &ch);
  149.     }
  150.     cp = canonb;
  151.     *cp = 0;
  152. #endif
  153.     cp2 = cp;
  154.     while (cp2 < canonb + BUFSIZ)
  155.         *cp2++ = 0;
  156.     cp2 = cp;
  157.     if (setjmp(rewrite))
  158.         goto redo;
  159. # ifdef VMUNIX
  160.     sigset(SIGCONT, ttycont);
  161. # endif VMUNIX
  162.     clearerr(stdin);
  163.     while (cp2 < canonb + BUFSIZ) {
  164.         c = getc(stdin);
  165.         if (c == EOF || c == '\n')
  166.             break;
  167.         *cp2++ = c;
  168.     }
  169.     *cp2 = 0;
  170. # ifdef VMUNIX
  171.     sigset(SIGCONT, signull);
  172. # endif VMUNIX
  173.     if (c == EOF && ferror(stdin) && hadcont) {
  174. redo:
  175.         hadcont = 0;
  176.         cp = strlen(canonb) > 0 ? canonb : NOSTR;
  177.         clearerr(stdin);
  178.         return(readtty(pr, cp));
  179.     }
  180. #ifndef TIOCSTI
  181.     if (cp == NOSTR || *cp == '\0')
  182.         return(src);
  183.     cp2 = cp;
  184.     if (!ttyset)
  185.         return(strlen(canonb) > 0 ? savestr(canonb) : NOSTR);
  186.     while (*cp != '\0') {
  187.         c = *cp++;
  188.         if (c == c_erase) {
  189.             if (cp2 == canonb)
  190.                 continue;
  191.             if (cp2[-1] == '\\') {
  192.                 cp2[-1] = c;
  193.                 continue;
  194.             }
  195.             cp2--;
  196.             continue;
  197.         }
  198.         if (c == c_kill) {
  199.             if (cp2 == canonb)
  200.                 continue;
  201.             if (cp2[-1] == '\\') {
  202.                 cp2[-1] = c;
  203.                 continue;
  204.             }
  205.             cp2 = canonb;
  206.             continue;
  207.         }
  208.         *cp2++ = c;
  209.     }
  210.     *cp2 = '\0';
  211. #endif
  212.     if (equal("", canonb))
  213.         return(NOSTR);
  214.     return(savestr(canonb));
  215. }
  216.  
  217. # ifdef VMUNIX
  218. /*
  219.  * Receipt continuation.
  220.  */
  221. ttycont()
  222. {
  223.  
  224.     hadcont++;
  225.     longjmp(rewrite, 1);
  226. }
  227. # endif VMUNIX
  228.  
  229. /*
  230.  * Null routine to satisfy
  231.  * silly system bug that denies us holding SIGCONT
  232.  */
  233. signull()
  234. {}
  235.